home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Commodities / ClipTool / src / gui.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  21KB  |  744 lines

  1. /*
  2.  *  ClipTool (Udklipsværktøj) - A Commodities Exchange Application
  3.  *  Copyright (C) 1994 Torsten Poulin
  4.  *
  5.  *  gui.c - the graphic user interface
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *             The author can be contacted by mail at
  22.  *               Torsten Poulin
  23.  *               Banebrinken 99, 2, 77
  24.  *               DK-2400 Copenhagen NV
  25.  *               Denmark
  26.  *             or via email: torsten@diku.dk
  27.  *
  28.  * $Log:    gui.c,v $
  29.  * Revision 1.1  94/02/20  21:31:46  Torsten
  30.  * Initial revision
  31.  * 
  32.  */
  33.  
  34. static char const RCSid[] = "$Id: gui.c,v 1.1 94/02/20 21:31:46 Torsten Exp $";
  35.  
  36. #include "cliptool.h"
  37. #include "ctstrings.h"
  38.  
  39. struct Menu *ctmenustrip;
  40.  
  41. static void eraseframe(struct Rectangle *);
  42. static void drawframe(struct Rectangle *);
  43.  
  44. static void *vi;
  45. static struct Gadget *glist;
  46. static BOOL hasmenus;
  47. static struct Rectangle rect;
  48. static struct Region *region;
  49. static prevLeft, prevTop, prevWidth, prevHeight;
  50.  
  51. static struct NewMenu ctmenu[] = {
  52. { NM_TITLE, 0, 0, 0, 0, 0,}, /* Project */
  53. {  NM_ITEM, 0, 0, 0, 0, 0,}, /* Open */
  54. {   NM_SUB, 0, 0, 0, 0, (void *) CTM_OPENTEXT,},
  55. {   NM_SUB, 0, 0, 0, 0, (void *) CTM_OPENFTXT,},
  56. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_SAVE,},
  57. {   NM_SUB, 0, 0, 0, 0, (void *) CTM_SAVETEXT,},
  58. {   NM_SUB, 0, 0, 0, 0, (void *) CTM_SAVEFTXT,},
  59. {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
  60. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_ABOUT,},
  61. {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
  62. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_HIDE,},
  63. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_QUIT,},
  64.  
  65. { NM_TITLE, 0, 0, 0, 0, 0,}, /* Edit */
  66. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_CUT,},
  67. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_COPY,},
  68. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_PASTE,},
  69. {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
  70. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_KILL,},
  71. {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
  72. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_PREV,},
  73. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_NEXT,},
  74.  
  75. { NM_TITLE, 0, 0, 0, 0, 0,}, /* Settings */
  76. {  NM_ITEM, 0, 0, 0, 0, (void *) CTM_UNIT,},
  77. {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
  78. {  NM_ITEM, 0, 0, CHECKIT | MENUTOGGLE, 0, (void *) CTM_ICONS,},
  79. {  NM_ITEM, 0, 0, CHECKIT | MENUTOGGLE, 0, (void *) CTM_APPICON,},
  80. {  NM_ITEM, 0, 0, CHECKIT | MENUTOGGLE | NM_ITEMDISABLED,
  81.      0, (void *) CTM_AUTO,}, /* not supported, yet :) */
  82.  
  83. { NM_END, NULL, 0, 0, 0, 0,},
  84. };
  85.  
  86.  
  87. void initnewmenustruct(void)
  88. {
  89.   /* Project menu */
  90.   ctmenu[0].nm_Label = ls(MSG_PROJECT_MENU);
  91.   ctmenu[1].nm_Label = ls(MSG_PROJECT_OPEN);
  92.   ctmenu[2].nm_Label = ls(MSG_PROJECT_OPENSAVEAS_TEXT);
  93.   ctmenu[2].nm_CommKey = ls(MSG_PROJECT_OPEN_KEY);
  94.   ctmenu[3].nm_Label = ls(MSG_PROJECT_OPENSAVEAS_FTXT);
  95.   ctmenu[4].nm_Label = ls(MSG_PROJECT_SAVEAS);
  96.   ctmenu[5].nm_Label = ls(MSG_PROJECT_OPENSAVEAS_TEXT);
  97.   ctmenu[5].nm_CommKey = ls(MSG_PROJECT_SAVEAS_KEY);
  98.   ctmenu[6].nm_Label = ls(MSG_PROJECT_OPENSAVEAS_FTXT);
  99.   ctmenu[8].nm_Label = ls(MSG_PROJECT_ABOUT);
  100.   ctmenu[10].nm_Label = ls(MSG_PROJECT_HIDE);
  101.   ctmenu[10].nm_CommKey = ls(MSG_PROJECT_HIDE_KEY);
  102.   ctmenu[11].nm_Label = ls(MSG_PROJECT_QUIT);
  103.   ctmenu[11].nm_CommKey = ls(MSG_PROJECT_QUIT_KEY);
  104.  
  105.   /* Edit menu */
  106.   ctmenu[12].nm_Label = ls(MSG_EDIT_MENU);
  107.   ctmenu[13].nm_Label = ls(MSG_EDIT_CUT);
  108.   ctmenu[13].nm_CommKey = ls(MSG_EDIT_CUT_KEY);
  109.   ctmenu[14].nm_Label = ls(MSG_EDIT_COPY);
  110.   ctmenu[14].nm_CommKey = ls(MSG_EDIT_COPY_KEY);
  111.   ctmenu[15].nm_Label = ls(MSG_EDIT_PASTE);
  112.   ctmenu[15].nm_CommKey = ls(MSG_EDIT_PASTE_KEY);
  113.   ctmenu[17].nm_Label = ls(MSG_EDIT_ERASE);
  114.   ctmenu[17].nm_CommKey = ls(MSG_EDIT_ERASE_KEY);
  115.   ctmenu[19].nm_Label = ls(MSG_EDIT_PREVIOUS);
  116.   ctmenu[19].nm_CommKey = ls(MSG_EDIT_PREVIOUS_KEY);
  117.   ctmenu[20].nm_Label = ls(MSG_EDIT_NEXT);
  118.   ctmenu[20].nm_CommKey = ls(MSG_EDIT_NEXT_KEY);
  119.  
  120.   /* Settings menu */
  121.   ctmenu[21].nm_Label = ls(MSG_SETTINGS_MENU);
  122.   ctmenu[22].nm_Label = ls(MSG_SETTINGS_CLIPUNIT);
  123.   ctmenu[22].nm_CommKey = ls(MSG_SETTINGS_CLIPUNIT_KEY);
  124.   ctmenu[24].nm_Label = ls(MSG_SETTINGS_CREATEICONS);
  125.   ctmenu[25].nm_Label = ls(MSG_SETTINGS_APPICON);
  126.   ctmenu[26].nm_Label = ls(MSG_SETTINGS_AUTOMATIC);
  127. }
  128.  
  129.  
  130. static UWORD chip appiconI1Data[] =
  131. {
  132.   /* Plane 0 */
  133.   0xFFFF,0xFFFF,0xFF00,0xC000,0x0000,0x0000,0xC000,0x0000,
  134.   0x0000,0xC001,0x5540,0x0000,0xC0FF,0xFFFF,0x0000,0xC0E0,
  135.   0xFF87,0x8000,0xC0E0,0x0007,0x8000,0xC0E6,0x9B67,0x8000,
  136.   0xC0E0,0x0007,0x8000,0xC0E7,0xCEC7,0x8000,0xC0E0,0x0007,
  137.   0x8000,0xC0E6,0xEA87,0x8000,0xC0E0,0x0007,0x8000,0xC0E7,
  138.   0x7987,0x8000,0xC0E0,0x0007,0x8000,0xC0E7,0x71FF,0x8000,
  139.   0xC0E0,0x010F,0x8000,0xC0E0,0x013F,0x8000,0xC0FF,0xFFFF,
  140.   0x8000,0xC0FF,0xFFFF,0x8000,0xC07F,0xFFFF,0x8000,0xC000,
  141.   0x0000,0x0000,0xC000,0x0000,0x0000,0x8000,0x0000,0x0000,
  142.   /* Plane 1 */
  143.   0x0000,0x0000,0x0080,0x0000,0x0000,0x0180,0x0000,0x0000,
  144.   0x0180,0x0001,0xFFC0,0x0180,0x0001,0xFFC0,0x0180,0x001F,
  145.   0xAAFC,0x8180,0x001F,0xFFFC,0x8180,0x0019,0x649C,0x8180,
  146.   0x001F,0xFFFC,0x8180,0x0018,0x313C,0x8180,0x001F,0xFFFC,
  147.   0x8180,0x0019,0x157C,0x8180,0x001F,0xFFFC,0x8180,0x0018,
  148.   0x867C,0x8180,0x001F,0xFFFC,0x8180,0x0018,0x8E00,0x8180,
  149.   0x001F,0xFEF8,0x8180,0x001F,0xFEE0,0x8180,0x001F,0xFF00,
  150.   0x8180,0x0000,0x0000,0x8180,0x007F,0xFFFF,0x8180,0x0000,
  151.   0x0000,0x0180,0x0000,0x0000,0x0180,0x7FFF,0xFFFF,0xFF80,
  152. };
  153.  
  154. static struct Image appiconI1 =
  155. {
  156.   0, 0,            /* Upper left corner */
  157.   41, 24, 2,        /* Width, Height, Depth */
  158.   appiconI1Data,    /* Image data */
  159.   0x0003, 0x0000,    /* PlanePick, PlaneOnOff */
  160.   NULL            /* Next image */
  161. };
  162.  
  163. static struct DiskObject appicon_do =
  164. {
  165.   0,            /* Magic Number */
  166.   0,            /* Version */
  167.   {            /* Embedded Gadget Structure */
  168.     NULL,        /* Next Gadget Pointer */
  169.     0, 0, 41, 25,    /* Left,Top,Width,Height */
  170.     0,            /* Flags */
  171.     0,            /* Activation Flags */
  172.     0,            /* Gadget Type */
  173.     (APTR)&appiconI1,    /* Render Image */
  174.     NULL,        /* Select Image */
  175.     NULL,        /* Gadget Text */
  176.     NULL,        /* Mutual Exclude */
  177.     NULL,        /* Special Info */
  178.     0,            /* Gadget ID */
  179.     NULL,        /* User Data (Revision) */
  180.   },
  181.   NULL,            /* Icon Type */
  182.   NULL,            /* Default Tool */
  183.   NULL,            /* Tool Type Array */
  184.   NO_ICON_POSITION,    /* Current X */
  185.   NO_ICON_POSITION,    /* Current Y */
  186.   NULL,            /* Drawer Structure */
  187.   NULL,            /* Tool Window */
  188.   0,            /* Stack Size */
  189. };
  190.  
  191.  
  192. void opendropicon(void)
  193. {
  194.   if (appicon_mp = CreateMsgPort()) {
  195.     aisigflag = 1 << appicon_mp->mp_SigBit;
  196.     appicon = AddAppIconA(0, 0, ls(MSG_CLIPTOOL), appicon_mp, NULL,
  197.               &appicon_do, NULL);
  198.   }  
  199. }
  200.  
  201.  
  202. void closedropicon(void)
  203. {
  204.   struct AppMessage *aimsg;
  205.  
  206.   if (appicon) RemoveAppIcon(appicon);
  207.   appicon = NULL;
  208.   if (appicon_mp) {
  209.     while (aimsg = (struct AppMessage *) GetMsg(appicon_mp))
  210.       ReplyMsg((struct Message *) aimsg);
  211.     DeleteMsgPort(appicon_mp);
  212.   }
  213.   appicon_mp = NULL;
  214. }
  215.  
  216.  
  217. void about(void)
  218. {
  219.   struct EasyStruct aboutreq;
  220.  
  221.   aboutreq.es_StructSize = sizeof(struct EasyStruct);
  222.   aboutreq.es_Flags = 0;
  223.   aboutreq.es_Title = ls(MSG_ABOUTCLIPTOOL);
  224.   aboutreq.es_TextFormat =
  225.     "%s - © 1994 Torsten Poulin (torsten@diku.dk)\n"
  226.     "(%s: \"%s\"  %s: \"%s\")\n\n"
  227.     "This program is free software; you can redistribute it and/or modify\n"
  228.     "it under the terms of the GNU General Public License as published by\n"
  229.     "the Free Software Foundation; either version 2 of the License , or\n"
  230.     "(at your option) any later version.\n\n"
  231.     "This program is distributed in the hope that it will be useful,\n"
  232.     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  233.     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
  234.     "GNU General Public License for more details.\n\n"
  235.     "You should have received a copy of the GNU General Public License\n"
  236.     "along with this program. If not, write to the Free Software\n"
  237.     "Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n";
  238.   aboutreq.es_GadgetFormat = ls(MSG_OK_GAD);
  239.  
  240.   EasyRequest(NULL, &aboutreq, NULL,
  241.           verstring, ls(MSG_PORTNAME), portname,
  242.           ls(MSG_HOTKEY), hotkey);
  243. }
  244.  
  245.  
  246. void msgreq(UBYTE *msg, UBYTE *name)
  247. {
  248.   struct EasyStruct msgreq;
  249.  
  250.   msgreq.es_StructSize = sizeof(struct EasyStruct);
  251.   msgreq.es_Flags = 0;
  252.   msgreq.es_Title = ls(MSG_CLIPTOOL);
  253.   msgreq.es_TextFormat = msg;
  254.   msgreq.es_GadgetFormat = ls(MSG_OK_GAD);
  255.  
  256.   EasyRequest(NULL, &msgreq, NULL, name);
  257. }
  258.  
  259.  
  260. /*
  261.  * Return the address of the menu-item with UserData = number.
  262.  * This makes it possible for us to find and check the state
  263.  * of the "Create menus?" item for instance.
  264.  *
  265.  * I could have used ItemAddress(), but I don't want to depend
  266.  * on the layout of the menus :)
  267.  */
  268.  
  269. struct MenuItem *findmenuitem(struct Menu *m, long number)
  270. {
  271.   struct MenuItem *mi, *si;
  272.  
  273.   for (; m; m = m->NextMenu)
  274.     for (mi = m->FirstItem; mi; mi = mi->NextItem) {
  275.       if (number == (long) GTMENUITEM_USERDATA(mi)) return mi;
  276.       for (si = mi->SubItem; si; si = si->NextItem)
  277.     if (number == (long) GTMENUITEM_USERDATA(si)) return si;
  278.     }
  279.   return NULL;
  280. }
  281.  
  282.  
  283. /*
  284.  * This function makes sure the flags controlled by
  285.  * the menu toggle items reflect what is shown in the menu.
  286.  * It's a shame that Intuition can't be trusted :-/
  287.  */
  288.  
  289. void synchronizechecked(void)
  290. {
  291.   struct MenuItem *mi;
  292.  
  293.   if (hasmenus && guiwin) {
  294.     if (mi = findmenuitem(ctmenustrip, CTM_ICONS))
  295.       createicons = mi->Flags & CHECKED;
  296.     if (mi = findmenuitem(ctmenustrip, CTM_APPICON))
  297.       usedropicon = mi->Flags & CHECKED;
  298.   }
  299. }
  300.  
  301.  
  302. /*
  303.  * Open the graphic user interface window.
  304.  * If it is already open, it is brought to the front.
  305.  *
  306.  * The window is also made a Workbench AppWindow, if possible.
  307.  * This may fail for a number of reasons, the most common one
  308.  * being that Workbench isn't open...
  309.  */
  310.  
  311. BOOL opengui(void)
  312. {
  313.   struct Screen *pubscr = NULL;
  314.   struct DrawInfo *scr_di;
  315.   struct MenuItem *mi;
  316.   WORD alternate[4];
  317.   BOOL simple = FALSE;
  318.  
  319.   if (guiwin) {
  320.     /* The GUI is already open; bring it to front */
  321.     if (guiminimized) {
  322.       ZipWindow(guiwin);
  323.       guiminimized = FALSE;
  324.     }
  325.     WindowToFront(guiwin);
  326.   }
  327.   else {
  328.     /* Make sure we don't get a nasty surprise when we clean up ... */
  329.     guiminimized = hasmenus = FALSE;
  330.     ctmenustrip = NULL;
  331.     glist = NULL;
  332.     vi = NULL;
  333.     region = NULL;
  334.     appwin_mp = NULL;
  335.     appwin = NULL;
  336.  
  337.     /* Get a lock on the default public screen */
  338.     if (pubscr = LockPubScreen(NULL)) {
  339.       if ((vi = GetVisualInfo(pubscr, TAG_END))) {
  340.     xoffset = pubscr->WBorLeft;
  341.     yoffset = pubscr->WBorTop + (pubscr->Font->ta_YSize + 1);
  342.     alternate[0] = 0;    /* LeftEdge */
  343.     alternate[1] = yoffset;    /* TopEdge */
  344.     alternate[2] = GUI_WIDTH; /* Width */
  345.     alternate[3] = GUI_HEIGHT; /* Height */
  346.  
  347.     /*
  348.      * Determine what kind of imagery we're going to use.
  349.      */
  350.     if (simplebuttons) simple = TRUE;
  351.     else if (scr_di = GetScreenDrawInfo(pubscr)) {
  352.       simple = scr_di->dri_Depth == 1;
  353.       FreeScreenDrawInfo(pubscr, scr_di);
  354.     }
  355.  
  356.     if (createbuttonbar(&glist, vi, simple)) {
  357.       if (ctmenustrip = CreateMenus(ctmenu, TAG_END)) {
  358.         if (LayoutMenus(ctmenustrip, vi, TAG_END)) {
  359.  
  360.           if (prevWidth == 0 || prevHeight == 0) {
  361.         /* Window hasn't been opened before */
  362.         prevLeft = 10;
  363.         prevTop = 20;
  364.         prevWidth = GUI_WIDTH;
  365.         prevHeight = GUI_HEIGHT;
  366.           }
  367.  
  368.           guiwin = OpenWindowTags(NULL,
  369.                       WA_Left, prevLeft,
  370.                       WA_Top, prevTop,
  371.                       WA_InnerWidth, prevWidth,
  372.                       WA_InnerHeight, prevHeight,
  373.                       WA_MinWidth, alternate[2],
  374.                       WA_MaxWidth, ~0,
  375.                       WA_MinHeight, alternate[3],
  376.                       WA_MaxHeight, ~0,
  377.                       WA_Zoom, &alternate[0],
  378.                       WA_Activate, TRUE,
  379.                       WA_AutoAdjust, TRUE,
  380.                       WA_DragBar, TRUE,
  381.                       WA_CloseGadget, TRUE,
  382.                       WA_DepthGadget, TRUE,
  383.                       WA_SizeGadget, TRUE,
  384.                       WA_SimpleRefresh, TRUE,
  385.                       WA_IDCMP, IDCMP_CLOSEWINDOW
  386.                       | IDCMP_REFRESHWINDOW
  387.                       | IDCMP_GADGETUP
  388.                       | IDCMP_MENUPICK
  389.                       | IDCMP_SIZEVERIFY,
  390.                       WA_PubScreen, pubscr,
  391.                       WA_Gadgets, glist,
  392.                       TAG_END);
  393.         }
  394.       }
  395.     }
  396.     UnlockPubScreen(NULL, pubscr); /* not needed anymore */
  397.       }
  398.       if (guiwin) {
  399.     if (guiwin->Width<GUI_WIDTH-50 || guiwin->Height<GUI_HEIGHT-15) {
  400.       return FALSE;    /* Window is too small to be safe */
  401.     }
  402.     else {
  403.       if (appwin_mp = CreateMsgPort()) {
  404.         awsigflag = 1 << appwin_mp->mp_SigBit;
  405.         appwin = AddAppWindowA(0, 0, guiwin, appwin_mp, NULL);
  406.       }
  407.       rect.MinX = xoffset + 4;
  408.       rect.MinY = yoffset + 21;
  409.       rect.MaxX = guiwin->Width - guiwin->BorderRight - 4;
  410.       rect.MaxY = guiwin->Height - guiwin->BorderBottom - 3;
  411.  
  412.       if (region = NewRegion()) {
  413.         if (OrRectRegion(region, &rect)) {
  414.           drawframe(&rect);
  415.           InstallClipRegion(guiwin->WLayer, region);
  416.           SetDrMd(guiwin->RPort, 0L);
  417.         
  418.           updatetitlebar();
  419.  
  420.           /* Set checkmarks */
  421.           if (mi = findmenuitem(ctmenustrip, CTM_ICONS))
  422.         if (createicons) mi->Flags |= CHECKED;
  423.           if (mi = findmenuitem(ctmenustrip, CTM_APPICON))
  424.         if (usedropicon) mi->Flags |= CHECKED;
  425.  
  426.           GT_RefreshWindow(guiwin, NULL);
  427.           hasmenus = SetMenuStrip(guiwin, ctmenustrip);
  428.           showtext();
  429.         }
  430.         else return FALSE;    /* OrRectRegion() failed */
  431.       }
  432.       else return FALSE;    /* no region */
  433.     }
  434.       }
  435.     }
  436.   }
  437.   return (BOOL) guiwin;
  438. }
  439.  
  440.  
  441. /*
  442.  * Close the GUI.
  443.  */
  444.  
  445. void closegui(void)
  446. {
  447.   struct AppMessage *awmsg;
  448.  
  449.   if (guiwin && region) DisposeRegion(region);
  450.   region = NULL;
  451.   if (hasmenus && guiwin) ClearMenuStrip(guiwin);
  452.   hasmenus = FALSE;
  453.  
  454.   if (appwin) RemoveAppWindow(appwin);
  455.   appwin = NULL;
  456.   if (appwin_mp) {
  457.     while (awmsg = (struct AppMessage *) GetMsg(appwin_mp))
  458.       ReplyMsg((struct Message *) awmsg);
  459.     DeleteMsgPort(appwin_mp);
  460.   }
  461.   appwin_mp = NULL;
  462.  
  463.   synchronizechecked(); /* remember states */
  464.  
  465.   if (guiwin) {
  466.     /* save the present size for later use */
  467.     prevLeft = guiwin->LeftEdge;
  468.     prevTop = guiwin->TopEdge;
  469.     prevWidth = guiwin->Width - xoffset - guiwin->BorderRight;
  470.     prevHeight = guiwin->Height - yoffset - guiwin->BorderBottom;
  471.     CloseWindow(guiwin);
  472.   }
  473.   guiwin = NULL;
  474.  
  475.   FreeMenus(ctmenustrip);
  476.   ctmenustrip = NULL;
  477.  
  478.   FreeGadgets(glist);
  479.   glist = NULL;
  480.  
  481.   FreeVisualInfo(vi);
  482.   vi = NULL;
  483. }
  484.  
  485.  
  486. /*
  487.  * Resize the display box.
  488.  */
  489.  
  490. BOOL newsize(void)
  491. {
  492.   rect.MinX = xoffset + 4;
  493.   rect.MinY = yoffset + 21;
  494.   rect.MaxX = guiwin->Width - guiwin->BorderRight - 4;
  495.   rect.MaxY = guiwin->Height - guiwin->BorderBottom - 3;
  496.  
  497.   InstallClipRegion(guiwin->WLayer, NULL);
  498.   eraseframe(&rect);
  499.   drawframe(&rect);
  500.   ClearRegion(region);
  501.   if (OrRectRegion(region, &rect))
  502.     InstallClipRegion(guiwin->WLayer, region);
  503.   else return FALSE; /* we're in trouble!!! */
  504.   return TRUE;
  505. }
  506.  
  507.  
  508. /*
  509.  * The functions below handle the display of text
  510.  */
  511.  
  512. static void eraseframe(struct Rectangle *rect)
  513. {
  514.   SetAPen(guiwin->RPort, 0);
  515.   RectFill(guiwin->RPort,
  516.        rect->MinX - 3, rect->MinY - 2,
  517.        rect->MaxX + 2 + 1, rect->MaxY + 1 + 1);
  518. }
  519.  
  520.  
  521. static void drawframe(struct Rectangle *rect)
  522. {
  523.   DrawBevelBox(guiwin->RPort,
  524.            rect->MinX - 2, rect->MinY - 1,
  525.            rect->MaxX - rect->MinX + 4, rect->MaxY - rect->MinY + 3,
  526.            GT_VisualInfo, vi, GTBB_Recessed, TRUE, TAG_END);
  527. }
  528.  
  529.  
  530. void showtext(void)
  531. {
  532.   long count, position;
  533.   struct textbuffer *tb;
  534.   struct TextFont *font;
  535.  
  536.   if (!guiwin) return;
  537.   font = guiwin->RPort->Font;
  538.  
  539.   SetRast(guiwin->RPort, 0);
  540.   if (!currentbuffer) return; /* nothing to display */
  541.   tb = currentbuffer->tb;
  542.   Move(guiwin->RPort, rect.MinX + 1, rect.MinY + font->tf_YSize);
  543.   SetAPen(guiwin->RPort, 1);
  544.  
  545.   for (; tb; tb = tb->next) {
  546.     position = 0;
  547.     count = 0;
  548.  
  549.     while (position <= tb->length) {
  550.       while (tb->data[count] != '\n' && count <= tb->length)
  551.     count++;
  552.       Text(guiwin->RPort, &tb->data[position], count - position);
  553.       while (tb->data[count] == '\n' && count <= tb->length) {
  554.     Move(guiwin->RPort,
  555.          rect.MinX + 1, guiwin->RPort->cp_y + font->tf_YSize + 1);
  556.     count++;
  557.       }
  558.       position = count;
  559.     }
  560.     if (guiwin->RPort->cp_y > rect.MaxY) return;
  561.   }
  562. }
  563.  
  564.  
  565. /*
  566.  * Unit number requester
  567.  */
  568.  
  569. void getunitnumber(void)
  570. {
  571.   struct TextAttr Topaz80 = { "topaz.font", 8, 0, 0, };
  572.   struct Window *unitreq;
  573.   void *unvi = NULL;
  574.   struct Gadget *unglist = NULL, *ungad;
  575.   struct NewGadget ng;
  576.   struct IntuiMessage *imsg;
  577.   long fheight;
  578.   BOOL done = FALSE;
  579.   long value = unitnumber;
  580.  
  581.   long oklen, cancellen, buttonlen, labellen, winwidth;
  582.   UBYTE *ok = ls(MSG_OK_GAD);
  583.   UBYTE *cancel = ls(MSG_CANCEL_GAD);
  584.   UBYTE *label = ls(MSG_CLIPBOARDUNIT_GAD);
  585.  
  586.   if (!guiwin) return;        /* just to be safe... */
  587.  
  588.   fheight = 8;
  589.  
  590.   /* Make the buttons wide enough for the text */
  591.   oklen = TextLength(guiwin->RPort, ok, strlen(ok));
  592.   cancellen = TextLength(guiwin->RPort, cancel, strlen(cancel));
  593.   buttonlen = 8 + (oklen > cancellen ? oklen : cancellen);
  594.  
  595.   labellen = TextLength(guiwin->RPort, label, strlen(label));
  596.  
  597.   if ((unvi = GetVisualInfo(guiwin->WScreen, TAG_END))) {
  598.  
  599.     ungad = CreateContext(&unglist);
  600.     ng.ng_VisualInfo = unvi;
  601.     ng.ng_TextAttr = &Topaz80;
  602.     ng.ng_GadgetText = ok;
  603.     ng.ng_Width = buttonlen;
  604.     ng.ng_Height = 14;
  605.     ng.ng_TopEdge = yoffset + fheight * 2 + 4;
  606.     ng.ng_LeftEdge = xoffset + 2;
  607.     ng.ng_GadgetID = 0;
  608.     ng.ng_Flags = 0;
  609.     ungad = CreateGadget(BUTTON_KIND, ungad, &ng, TAG_END);
  610.  
  611.     ng.ng_GadgetText = cancel;
  612.     ng.ng_LeftEdge += buttonlen + 4;
  613.     ng.ng_GadgetID = 1;
  614.     ungad = CreateGadget(BUTTON_KIND, ungad, &ng, TAG_END);
  615.  
  616.     ng.ng_GadgetText = label;
  617.     ng.ng_Width = 8 * 5 + 8;
  618.     ng.ng_Height = 14;
  619.     ng.ng_TopEdge = yoffset + 3;
  620.     ng.ng_LeftEdge = xoffset + 2 + labellen + 8;
  621.     ng.ng_Flags = PLACETEXT_LEFT;
  622.     ng.ng_GadgetID = 2;
  623.     ungad = CreateGadget(INTEGER_KIND, ungad, &ng,
  624.              GTIN_Number, unitnumber,
  625.              GTIN_MaxChars, 4,
  626.              STRINGA_Justification, GACT_STRINGLEFT,
  627.              STRINGA_ReplaceMode, TRUE,
  628.              TAG_END);
  629.  
  630.     winwidth = ng.ng_Width + ng.ng_LeftEdge + 2;
  631.  
  632.     if (ungad) {
  633.       unitreq = OpenWindowTags(NULL,
  634.                    WA_Left, guiwin->LeftEdge + xoffset + 1,
  635.                    WA_Top, guiwin->TopEdge + yoffset + 1,
  636.                    WA_InnerWidth, winwidth,
  637.                    WA_InnerHeight, 4 * fheight + 4,
  638.                    WA_Activate, TRUE, WA_AutoAdjust, TRUE,
  639.                    WA_DragBar, TRUE, WA_DepthGadget, TRUE,
  640.                    WA_SimpleRefresh, TRUE,
  641.                    WA_Title, ls(MSG_CLIPTOOL),
  642.                    WA_IDCMP, IDCMP_REFRESHWINDOW
  643.                    | IDCMP_GADGETUP,
  644.                    WA_PubScreen, guiwin->WScreen,
  645.                    WA_Gadgets, unglist,
  646.                    TAG_END);
  647.       if (unitreq) {
  648.     GT_RefreshWindow(unitreq, NULL);
  649.     while (!done) {
  650.       WaitPort(unitreq->UserPort);
  651.       while (imsg = GT_GetIMsg(unitreq->UserPort)) {
  652.         switch(imsg->Class) {
  653.         case IDCMP_GADGETUP:
  654.           ungad = (struct Gadget *) imsg->IAddress;
  655.           switch (ungad->GadgetID) {
  656.           case 0: unitnumber = value; done = TRUE; break;
  657.           case 1: done = TRUE; break;
  658.           case 2:
  659.         value = ((struct StringInfo *) ungad->SpecialInfo)->LongInt;
  660.         if (value < 0 || value > 255) {
  661.           DisplayBeep(guiwin->WScreen);
  662.           GT_SetGadgetAttrs(ungad, unitreq, NULL,
  663.                     GTIN_Number, value = unitnumber,
  664.                     TAG_END);
  665.         }
  666.         break;
  667.           }
  668.           break;
  669.         case IDCMP_REFRESHWINDOW:
  670.           GT_BeginRefresh(unitreq);
  671.           GT_EndRefresh(unitreq, TRUE);
  672.           break;
  673.         }
  674.         GT_ReplyIMsg(imsg);
  675.       }
  676.     }
  677.     CloseWindow(unitreq);
  678.       }
  679.     }
  680.     FreeGadgets(unglist);
  681.     FreeVisualInfo(unvi);
  682.   }
  683. }
  684.  
  685.  
  686. static char titletxt[50];
  687.  
  688. void updatetitlebar(void)
  689. {
  690.   if (guiwin) {
  691.     if (ntotal == 0) strcpy(titletxt, ls(MSG_EMPTYGUITITLE));
  692.     else sprintf(titletxt, ls(MSG_GUITITLE), ncurrent, ntotal);
  693.     SetWindowTitles(guiwin, titletxt, NULL);
  694.   }
  695. }
  696.  
  697.  
  698. /*
  699.  * Ghost unavailable menu items if applicable.
  700.  * mistate() disables an item if state==FALSE, and enables it
  701.  * otherwise.
  702.  */
  703.  
  704. static void mistate(long id, BOOL state)
  705. {
  706.   struct MenuItem *mi;
  707.  
  708.   mi = findmenuitem(ctmenustrip, id);
  709.   if (state) mi->Flags |= ITEMENABLED; 
  710.   else mi->Flags &= ~ITEMENABLED;
  711. }
  712.  
  713.  
  714. void ghosting(void)
  715. {
  716.   static BOOL ghosted = FALSE;
  717.  
  718.   if (guiwin)
  719.   {
  720.     if (ghosted && ntotal > 0) {
  721.       ClearMenuStrip(guiwin);
  722.       mistate(CTM_SAVE, TRUE);
  723.       mistate(CTM_CUT, TRUE);
  724.       mistate(CTM_COPY, TRUE);
  725.       mistate(CTM_KILL, TRUE);
  726.       mistate(CTM_PREV, TRUE);
  727.       mistate(CTM_NEXT, TRUE);
  728.       ResetMenuStrip(guiwin, ctmenustrip);
  729.       ghosted = FALSE;
  730.     }
  731.     if (!ghosted && ntotal == 0) {
  732.       ClearMenuStrip(guiwin);
  733.       mistate(CTM_SAVE, FALSE); /* takes care of sub-items, too */
  734.       mistate(CTM_CUT,  FALSE);
  735.       mistate(CTM_COPY, FALSE);
  736.       mistate(CTM_KILL, FALSE);
  737.       mistate(CTM_PREV, FALSE);
  738.       mistate(CTM_NEXT, FALSE);
  739.       ResetMenuStrip(guiwin, ctmenustrip);
  740.       ghosted = TRUE;
  741.     }
  742.   }
  743. }
  744.